package loader.dewey;

import java.io.IOException;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Map;
import java.util.Stack;

import javax.xml.parsers.ParserConfigurationException;

import loader.LoaderXml;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;

import utils.database.DB;
import utils.database.DBStream;


public class DeweyLoaderXml extends LoaderXml 
{
	final int MAX_DEPTH = 30;
	private Stack<DeweyXmlElement> buffer = new Stack<DeweyXmlElement>();
	private int[] dewey;
	private int currentDewey = 0;
	private int document_id;
	
	public DeweyLoaderXml() throws ParserConfigurationException,
			SAXException {
		super();	
	}
	
	@Override
	public void Load(String xml_path) throws SAXException, IOException, SQLException {
		// TODO Auto-generated method stub		
		init();
		
		super.Load(xml_path);		
	}
	
	private int createDocumentId() throws SQLException {
		Statement sta = DB.getConnection().createStatement();
		sta.executeUpdate("INSERT INTO \"Documents\" VALUES (nextval('\"Documents_document_id_seq\"'::regclass))", Statement.RETURN_GENERATED_KEYS);
		ResultSet rs = sta.getGeneratedKeys();
		rs.next();
		return rs.getInt(1);
	}
	
	private void init() throws SQLException
	{
		dewey = new int[MAX_DEPTH];
		
		for(int i = 0; i < dewey.length ; i++)
		{
			dewey[i] = 0;
		}
		
		buffer.clear();
		
		document_id = createDocumentId();	
	}

	@Override
	public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException 
	{		
		super.startElement(uri, localName, qName, attributes);
				
		DeweyXmlElement element = new DeweyXmlElement();
		element.setDewey(getDewey());
		element.setDocument_id(document_id);		
		element.setPath_id(getPathId(current_path_node.toString()));
		
		for(int i = 0; i < attributes.getLength(); i++)
		{			
			DeweyXmlAttribute att = new DeweyXmlAttribute();
			att.setName(attributes.getQName(i));
			att.setValue(attributes.getValue(i));
			att.setParent_dewey(element.getDewey());
			
			element.addAttribute(att);
		}
				
		currentDewey++;
		dewey[currentDewey] = 0;
		
		buffer.push(element);
	}
	
	@Override
	public void endElement(String uri, String localName, String qName)
			throws SAXException {
		// TODO Auto-generated method stub
		super.endElement(uri, localName, qName);
		
		DeweyXmlElement el = buffer.pop();		
		el.setValue(text_atual.toString().trim());
				
		try {
			InsertInDB(el);
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}		
		
		currentDewey--;
		dewey[currentDewey]++;
		
		text_atual.delete(0, text_atual.length());
	}
	
	private void InsertInDB(DeweyXmlElement elem) throws SQLException
	{
		//Inserting element.				
		String query = "(" + document_id + ", '" + 
					DBStream.cleanup(elem.getDewey()) + "'," +
					elem.getPath_id() + ",'" +
					DBStream.cleanup(elem.getValue()) + "')";		
		DBStream.addElement(query);
		
		for(DeweyXmlAttribute item : elem.getAttributes())
		{							
			String queryAttribute = "(" + document_id + ", '" + DBStream.cleanup(item.getParent_dewey()) + "','" + DBStream.cleanup(item.getName()) + "','" + DBStream.cleanup(item.getValue()) + "')";
			DBStream.addAttribute(queryAttribute);
		}
		
		if(DBStream.canFlush())
			DBStream.flush(); 
	}
	
	@Override
	public void endDocument() throws SAXException {
		// TODO Auto-generated method stub
		super.endDocument();
		
		try {
			InsertInDBPathIds();
			DBStream.flush();
			System.out.println("Fim da Leitura");
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	private void InsertInDBPathIds() throws SQLException 
	{
		for(Map.Entry<String, Integer> item : path_ids.entrySet())
		{
			String query = "(" + document_id + "," + item.getValue() + ",'" + DBStream.cleanup(item.getKey()) + "')";
			DBStream.addPaths(query);
		}		
	}

	private String getDewey() 
	{
		StringBuffer b = new StringBuffer();
		
		for(int i = 0; i <= currentDewey; i++)
		{			
			String temp = "0000000";
			try
			{
				b.append(temp.substring(0, temp.length() - ((Integer)dewey[i]).toString().length() ) + dewey[i] + ".");
			}
			catch(Exception e)
			{
				System.out.println(b.toString());
				System.out.println("i >> " + dewey[i] + " length >> " + ((Integer)dewey[i]).toString().length());
				try {
					Thread.sleep(200000);
				} catch (InterruptedException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
			}
		}
		
		b.setLength(b.length() - 1);
		
		return b.toString();
	}
}
